﻿using BlazorAdmin.Interface;
using BlazorAdmin.Logs;
using BlazorAdmin.Models;
using BlazorAdmin.Models.Dto;
using BlazorAdmin.Tcp.Protocol;
using BlazorAdmin.Tcp.Server;
using BootstrapBlazor.Components;
using Newtonsoft.Json;
using System.Net;

namespace Pangeo.Admin.Web.Shared.Services
{
    /// <summary>
    /// Tcp业务服务类
    /// </summary>
    public class DeviceTcpService
    {
        private readonly TcpServer<DeviceTcpToken> tcpServer;
        private readonly IDevice clientService;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="tcpServer"></param>
        /// <param name="clientService"></param>
        public DeviceTcpService(TcpServer<DeviceTcpToken> tcpServer, IDevice clientService)
        {
            this.tcpServer = tcpServer;
            this.clientService = clientService;
            this.tcpServer.OnReviced += TcpServer_OnReviced;
        }
        
        private async void TcpServer_OnReviced(DeviceTcpToken token, ProtocolBase entity)
        {
            DeviceInfo? devRegInfo = null;
            var error = string.Empty;
            var cEntity = (DeviceProtocol)entity;

            if (cEntity.DataCache != null && cEntity.DataCache.TryGetValue(TcpPolicy.GUID, out var clientID))
            {
                token.ID = clientID?.ToString();
                if (!string.IsNullOrEmpty(token.ID))
                {
                    try
                    {
                        if (string.IsNullOrEmpty(token.ID) || null == token.Client)
                            return;
                        if (token.Client.RemoteEndPoint is not IPEndPoint point)
                            return;

                        var device = new Device()
                        {
                            Guid = token.ID,
                            IP = point.Address.ToString(),
                            Version = cEntity.Version
                        };

                        if (cEntity.DataCache.TryGetValue(TcpPolicy.Registration, out var registInfo))
                        {
                            devRegInfo = JsonConvert.DeserializeObject<DeviceInfo>(registInfo.ToString());
                            if (devRegInfo != null)
                            {
                                device.OS = devRegInfo.os;
                                device.Mac = devRegInfo.mac;
                                device.Host = devRegInfo.host;
                                device.Location = devRegInfo.location;
                                device.AssetNo = devRegInfo.asset_no;
                                device.BackupDir = devRegInfo.backup_path;
                                device.UploadPath = devRegInfo.uploaded_path;
                            }

                            LogUtil.Info($"收到客户端设备信息 {JsonConvert.SerializeObject(devRegInfo)}");
                        }
                        else
                        {
                            LogUtil.Info($"收到心跳 {device.IP} {device.Guid} {device.Version}");
                        }

                        await clientService.InsertOrUpdate(device);
                    }
                    catch (Exception ex)
                    {
                        error = ex.ToString();
                    }
                }
            }

            if (tcpServer.Console != null)
            {
                cEntity.DataCache.TryGetValue(TcpPolicy.Registration, out var registInfo);
                _ = Task.Run(async () =>
                {
                    var split = "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~";
                    tcpServer.Console.Invoke(Color.Success, $"{split} {token.ClientPoint} 心跳 {split}");
                    tcpServer.Console.Invoke(Color.Success, $"客户端ID : {token.ID}    v{cEntity.Version}");
                    tcpServer.Console.Invoke(Color.Success, $"连接时间 : {token.ConnectTime.ToString("yyyy-MM-dd HH:mm:ss")}");

                    if (devRegInfo != null)
                    {
                        var data = JsonConvert.SerializeObject(devRegInfo, new JsonSerializerSettings()
                        {
                            NullValueHandling = NullValueHandling.Ignore
                        });
                        tcpServer.Console.Invoke(Color.Success, $"发送数据 : {data}");
                    }

                    if (!string.IsNullOrEmpty(error))
                        tcpServer.Console.Invoke(Color.Danger, $"检查并添加新的客户端信息出错:\n {error}");
                });
            }
        }
    }
}
